package com.soup.hummingbird.module.method.bytebuddy;

import com.google.common.base.Joiner;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.implementation.bind.annotation.AllArguments;
import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall;

import java.lang.reflect.Method;
import java.util.concurrent.Callable;

/**
 * 〈方法耗时统计〉<br>
 *
 * @author zhaoyi
 */
@Slf4j
public class MethodCostTime {

    @RuntimeType
    public static Object intercept(@Origin Method method, @AllArguments Object[] args, @SuperCall Callable<?> callable) throws Exception {
        long start = System.currentTimeMillis();
        Object resObj = null;
        try {
            // 原有函数执行
            resObj = callable.call();
            return resObj;
        } finally {
            String methodName = method.getName();
            int parameterCount = method.getParameterCount();
            Class<?>[] parameterTypeClasses = method.getParameterTypes();
            String[] parameterTypes = new String[parameterCount];
            for (int i = 0; i < parameterCount; i++) {
                parameterTypes[i] = parameterTypeClasses[i].getTypeName();
            }
            String paramsTyps = Joiner.on(",").join(parameterTypes);
            String paramsVals = Joiner.on(",").join(args);
            String returnType = method.getReturnType().getName();
            long consumeTime = System.currentTimeMillis() - start;


            log.info("方法名称:{},入参数量:{},入参类型:{},入参内容:{},出参类型:{},出参结果:{},方法耗时:{}ms",
                    methodName, parameterCount, paramsTyps, paramsVals, returnType, resObj, consumeTime);

            // System.out.println("方法名称：" + methodName);
            // System.out.println("入参个数：" + parameterCount);
            // System.out.println("入参类型：" + paramsTyps);
            // System.out.println("入参内容：" + paramsVals);
            // System.out.println("出参类型：" + returnType);
            // System.out.println("出参结果：" + resObj);
            // System.out.println("方法耗时：" + consumeTime + "ms");
        }
    }

}
